# This controller handles the login/logout function of the site.  
class CuentasController < ApplicationController
  before_filter :login_required, :only => [ :change_password ]
    
  # Formulario identificador de usuarios.
  def new
    @usuario = Usuario.new(params[:usuario])
  end

  # Método identificador de usuarios. 
  def create
    if using_open_id?
      open_id_authentication(params[:openid_url])
    else
      password_authentication(params[:login], params[:password])
    end    
  end
  
  # Termina con la session de un usuario.
  def destroy
    if logged_in?
      self.current_usuario.update_attributes(:last_seen_at => nil)
      self.current_usuario.forget_me       
    end
    cookies.delete :auth_token
    reset_session
    flash[:notice] = "¡ Hasta pronto !"
    redirect_back_or_default('/')
  end  
  
  # En caso de que el usuario haya solicitado un cambio de email, este
  # método confirmará que el +email_activaction_code+ que le ha llegado
  # a la nueva dirección sea válida.
  def activate_new_email
    flash.clear  
    return unless params[:id].nil? or params[:email_activation_code].nil?
    activator = params[:id] || params[:email_activation_code]
    @usuario = Usuario.find_by_email_activation_code(activator) 
    if @usuario and @usuario.activate_new_email
      flash[:notice] = "El email ha sido actualizado" 
    else
      flash[:error] = "No se ha podido actualizar el email" 
    end
    if logged_in?
      redirect_to usuario_home_path(current_usuario.login)
    else
      redirect_back_or_default('/')
    end
  end
  
  # Método que permite cambiar la contraseña. No se utiliza aún.
  def change_password
    return unless request.post?
    if Usuario.authenticate(current_usuario.login, params[:old_password])
      if ((params[:password] == params[:password_confirmation]) && !params[:password_confirmation].blank?)
        current_usuario.password_confirmation = params[:password_confirmation]
        current_usuario.password = params[:password]

        if current_usuario.save
          flash[:notice] = "Password ha sido cambiado." 
          redirect_to main_url and return
        else
          flash[:error] = "Password no ha sido cambiado." 
        end

      else
        flash[:error] = "La nueva contraseña no coincide." 
        @old_password = params[:old_password]
      end
    else
      flash[:error] = "La contraseña anterior es incorrecta." 
    end
  end
  
  # Acción/método que envia un correo al usuario con el enlace que
  # permite cambiar tu contraseña.  
  def forgot_password
    return unless request.post?
    @usuario = Usuario.find_by_email(params[:usuario][:email])
    if @usuario && !@usuario.open_id_url?
      @usuario.forgot_password 
      @usuario.save
      flash[:notice] = "Hemos mandado a tu email las instrucciones necesarias para que puedas resetear tu contraseña." 
    elsif @usuario && @usuario.open_id_url?
      flash[:error] = "El email está asociado a una cuenta OpenID."
    else
      flash[:error] = "No hemos conseguido localizar este email." 
    end            
    redirect_back_or_default('/')
  end
  
  # Acción donde se encuentra la lógica de cambio de contraseña.  
  def reset_password
    begin  
      @usuario = Usuario.find_by_password_reset_code(params[:id])

      return if @usuario unless params[:usuario]

      if ((params[:usuario][:password] == params[:usuario][:password_confirmation]) && !params[:usuario][:password_confirmation].blank?)
        self.current_usuario = @usuario #for the next two lines to work
        current_usuario.password_confirmation = params[:usuario][:password_confirmation]
        current_usuario.password = params[:usuario][:password]
        @usuario.reset_password
        if current_usuario.save
          flash[:notice] = "¡ Has modificado tu contraseña con exito !"
          redirect_to usuario_home_path(current_usuario.login)
        end
      else
        flash[:error] = "Las contraseñas no coinciden"
      end  
    rescue
      logger.error "Invalid Reset Code entered" 
      flash[:error] = "Has insertado un codigo invalido de reseteo. Por favor revisalo y prueba de nuevo." 
      redirect_back_or_default('/')
    end
  end    
  
protected
  def open_id_authentication(openid_url)
    authenticate_with_open_id(openid_url, :required => [:nickname, :email]) do |result, identity_url, registration|
      if result.successful?
        if registration['nickname'].not.blank? && registration['email'].not.blank?
          @user = Usuario.find_or_initialize_by_open_id_url(identity_url)
          if @user.new_record?
            @user.login = registration['nickname']
            @user.email = registration['email']
            @user.save(false)
          end
          self.current_usuario = @user
          successful_login
        else
          failed_login "El nick y el email son requeridos"
        end
      else
        failed_login result.message
      end
    end
  end

  def password_authentication(login, password)
    self.current_usuario = Usuario.authenticate(login, password)
    if logged_in?
      successful_login
    else
      failed_login("Usuario/password erroneo.")
    end
  end

  def failed_login(message = "Authentication failed.")
    flash[:error] = message
    redirect_back_or_default('/')
  end

  def successful_login
    if params[:remember_me] == "1"
      self.current_usuario.remember_me
      cookies[:auth_token] = { :value => self.current_usuario.remember_token , :expires => self.current_usuario.remember_token_expires_at }
    end
    redirect_back_or_default('/')
    flash[:notice] = "¡Bienvenido #{current_usuario.login}!"
  end 
end
